Ring_buffer.c

					
#include <stdlib.h>
#include <string.h>

#include "Ring_buffer.h"

/*********************************
typedef struct
{
  uint8_t* samples;
  uint16_t buffer_size;
  uint16_t head;
  uint16_t tail;
  uint16_t bytes_avail;
  unsigned long samples_taken_total;
  my_bool lock;
} queue_t;
*********************************/

void init_buffer(queue_t* Buffer, uint16_t samples_amount)
{
    Buffer->samples = (uint8_t*)malloc(samples_amount);
    Buffer->buffer_size = samples_amount;
    Buffer->bytes_written = 0;
	Buffer->samples_taken_total = 0;
	Buffer->lock = 0;
}

/*  Function to find the lesser value between two arguments
 */
uint16_t min_val(uint16_t a, uint16_t b)
{
  return a < b ? a : b; // if a is smaller than b - return a. Otherwise b
}

/* inserting a sample into the buffer.
 * Arguments:
 *  Buffer - pointer to the Buffer (ring Buffer) we are working with
 *  data - pointer to the data to be inserted
 *  Size - amount of bytes to be inserted (max 255 - uint8_t)
 */
my_bool put_sample(queue_t* Buffer, volatile uint8_t* data, uint8_t Size)
{
	if(Buffer->lock == 0)
	{
		Buffer->lock = 1;										  // Lock out the buffer to prevent interrupting by other instances during writing
		if((Buffer->buffer_size - Buffer->bytes_written) < Size)  // Checking if there still any free space in the buffer
		{
			Buffer->lock = 0;
			return LOW;											  // if it's false then the buffer is overflown
		}

		const uint8_t part1 = min_val(Size, (Buffer->buffer_size - Buffer->tail));
		const uint8_t part2 = Size - part1;

		memcpy((void*)(Buffer->samples + Buffer->tail), (const void*)data,           part1);
		memcpy((void*)Buffer->samples,                  (const void*)(data + part1), part2);

		Buffer->tail = (Buffer->tail + Size) % Buffer->buffer_size;
		Buffer->bytes_written += Size;

		Buffer->samples_taken_total += Size;    // controlling how many data samples have been taken
		
		Buffer->lock = 0;
		return HIGH;
	}
	else
		return LOW; // so far there is no noticing if the buffer was locked by the last writing try
}

/* Getting data out of the ring Buffer
 *  Arguments: 
 *    Buffer - pointer to the Buffer (ring Buffer) we are working with
 *    data - pointer to the variable where the readed data will be stored
 *    Size - amount of bytes to be readed (max 255 - uint8_t)
 */
my_bool get_sample(queue_t* Buffer, uint8_t* data, uint8_t Size)
{
	if(Buffer->lock == 0)
	{
		Buffer->lock = 1;										  // Lock out the buffer to prevent interrupting by other instances during writing
		if(Buffer->bytes_written < Size)  // if we want to read more than available - return LOW
		{
			Buffer->lock = 0;	
			return LOW;
		}

		const uint8_t part1 = min_val(Size, Buffer->buffer_size - Buffer->head);
		const uint8_t part2 = Size - part1;

		memcpy(data,         Buffer->samples + Buffer->head, part1);
		memcpy(data + part1, Buffer->samples,                part2);

		Buffer->head = (Buffer->head + Size) % Buffer->buffer_size;
		Buffer->bytes_written -= Size;
		Buffer->lock = 0;
		return HIGH;
	}
	else
		return LOW;
}